//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.WebControls;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Services.Localization;
namespace DotNetNuke.UI.WebControls
{
	public class DualListBox : WebControl, IPostBackEventHandler, IPostBackDataHandler
	{
		private Style _AvailableListBoxStyle = new Style();
		private TableStyle _ContainerStyle = new TableStyle();
		private Style _ButtonStyle = new Style();
		private Style _HeaderStyle = new Style();
		private Style _SelectedListBoxStyle = new Style();
		private object _AvailableDataSource;
		private object _SelectedDataSource;
		private string _DataTextField;
		private string _DataValueField;
		private string _LocalResourceFile;
		private string _AddAllImageURL;
		private string _AddAllKey;
		private string _AddAllText;
		private string _AddImageURL;
		private string _AddKey;
		private string _AddText;
		private string _RemoveAllImageURL;
		private string _RemoveAllKey;
		private string _RemoveAllText;
		private string _RemoveImageURL;
		private string _RemoveKey;
		private string _RemoveText;
		private List<string> _AddValues;
		private List<string> _RemoveValues;
		public event DualListBoxEventHandler AddButtonClick;
		public event EventHandler AddAllButtonClick;
		public event DualListBoxEventHandler RemoveButtonClick;
		public event EventHandler RemoveAllButtonClick;
		public string AddAllImageURL {
			get { return _AddAllImageURL; }
			set { _AddAllImageURL = value; }
		}
		public string AddAllKey {
			get { return _AddAllKey; }
			set { _AddAllKey = value; }
		}
		public string AddAllText {
			get { return _AddAllText; }
			set { _AddAllText = value; }
		}
		public string AddImageURL {
			get { return _AddImageURL; }
			set { _AddImageURL = value; }
		}
		public string AddKey {
			get { return _AddKey; }
			set { _AddKey = value; }
		}
		public string AddText {
			get { return _AddText; }
			set { _AddText = value; }
		}
		public object AvailableDataSource {
			get { return _AvailableDataSource; }
			set { _AvailableDataSource= value; }
		}
		public string DataTextField {
			set { _DataTextField= value; }
		}
		public string DataValueField {
			set { _DataValueField= value; }
		}
		public string LocalResourceFile {
			get { return _LocalResourceFile; }
			set { _LocalResourceFile = value; }
		}
		public string RemoveAllImageURL {
			get { return _RemoveAllImageURL; }
			set { _RemoveAllImageURL = value; }
		}
		public string RemoveAllKey {
			get { return _RemoveAllKey; }
			set { _RemoveAllKey = value; }
		}
		public string RemoveAllText {
			get { return _RemoveAllText; }
			set { _RemoveAllText = value; }
		}
		public string RemoveImageURL {
			get { return _RemoveImageURL; }
			set { _RemoveImageURL = value; }
		}
		public string RemoveKey {
			get { return _RemoveKey; }
			set { _RemoveKey = value; }
		}
		public string RemoveText {
			get { return _RemoveText; }
			set { _RemoveText = value; }
		}
		public object SelectedDataSource {
			get { return _SelectedDataSource; }
			set { _SelectedDataSource= value; }
		}
		[Browsable(true), Category("Styles"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.InnerProperty), TypeConverter(typeof(ExpandableObjectConverter)), Description("Set the Style for the Available List Box.")]
		public Style AvailableListBoxStyle {
			get { return _AvailableListBoxStyle; }
		}
		[Browsable(true), Category("Styles"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.InnerProperty), TypeConverter(typeof(ExpandableObjectConverter)), Description("Set the Style for the Button.")]
		public Style ButtonStyle {
			get { return _ButtonStyle; }
		}
		[Browsable(true), Category("Styles"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.InnerProperty), TypeConverter(typeof(ExpandableObjectConverter)), Description("Set the Style for the Container.")]
		public TableStyle ContainerStyle {
			get { return _ContainerStyle; }
		}
		[Browsable(true), Category("Styles"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.InnerProperty), TypeConverter(typeof(ExpandableObjectConverter)), Description("Set the Style for the Header.")]
		public Style HeaderStyle {
			get { return _HeaderStyle; }
		}
		[Browsable(true), Category("Styles"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.InnerProperty), TypeConverter(typeof(ExpandableObjectConverter)), Description("Set the Style for the Selected List Box.")]
		public Style SelectedListBoxStyle {
			get { return _SelectedListBoxStyle; }
		}
		private NameValueCollection GetList(string listType, object dataSource)
		{
			IEnumerable dataList = dataSource as IEnumerable;
			NameValueCollection list = new NameValueCollection();
			if (dataList == null) {
				throw new ArgumentException("The " + listType + "DataSource must implement the IEnumerable Interface");
			} else {
				foreach (object item in dataList) {
					BindingFlags bindings = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
					PropertyInfo objTextProperty = item.GetType().GetProperty(_DataTextField, bindings);
					PropertyInfo objValueProperty = item.GetType().GetProperty(_DataValueField, bindings);
					string objValue = Convert.ToString(objValueProperty.GetValue(item, null));
					string objText = Convert.ToString(objTextProperty.GetValue(item, null));
					list.Add(objText, objValue);
				}
			}
			return list;
		}
		private void RenderButton(string buttonType, HtmlTextWriter writer)
		{
			string buttonText = Null.NullString;
			string imageURL = Null.NullString;
			writer.RenderBeginTag(HtmlTextWriterTag.Tr);
			writer.RenderBeginTag(HtmlTextWriterTag.Td);
			switch (buttonType) {
				case "Add":
					if (string.IsNullOrEmpty(AddKey)) {
						buttonText = AddText;
					} else {
						buttonText = Localization.GetString(AddKey, LocalResourceFile);
					}
					imageURL = AddImageURL;
					break;
				case "AddAll":
					if (string.IsNullOrEmpty(AddAllKey)) {
						buttonText = AddAllText;
					} else {
						buttonText = Localization.GetString(AddAllKey, LocalResourceFile);
					}
					imageURL = AddAllImageURL;
					break;
				case "Remove":
					if (string.IsNullOrEmpty(RemoveKey)) {
						buttonText = RemoveText;
					} else {
						buttonText = Localization.GetString(RemoveKey, LocalResourceFile);
					}
					imageURL = RemoveImageURL;
					break;
				case "RemoveAll":
					if (string.IsNullOrEmpty(RemoveAllKey)) {
						buttonText = RemoveAllText;
					} else {
						buttonText = Localization.GetString(RemoveAllKey, LocalResourceFile);
					}
					imageURL = RemoveAllImageURL;
					break;
			}
			writer.AddAttribute(HtmlTextWriterAttribute.Href, Page.ClientScript.GetPostBackClientHyperlink(this, buttonType));
			writer.AddAttribute(HtmlTextWriterAttribute.Title, buttonText);
			writer.RenderBeginTag(HtmlTextWriterTag.A);
			if (!string.IsNullOrEmpty(imageURL)) {
				writer.AddAttribute(HtmlTextWriterAttribute.Src, ResolveClientUrl(imageURL));
				writer.AddAttribute(HtmlTextWriterAttribute.Title, buttonText);
				writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
				writer.RenderBeginTag(HtmlTextWriterTag.Img);
				writer.RenderEndTag();
			} else {
				writer.Write(buttonText);
			}
			writer.RenderEndTag();
			writer.RenderEndTag();
			writer.RenderEndTag();
		}
		private void RenderButtons(HtmlTextWriter writer)
		{
			writer.RenderBeginTag(HtmlTextWriterTag.Table);
			RenderButton("Add", writer);
			RenderButton("AddAll", writer);
			writer.RenderBeginTag(HtmlTextWriterTag.Tr);
			writer.RenderBeginTag(HtmlTextWriterTag.Td);
			writer.Write("&nbsp;");
			writer.RenderEndTag();
			writer.RenderEndTag();
			RenderButton("Remove", writer);
			RenderButton("RemoveAll", writer);
			writer.RenderEndTag();
		}
		private void RenderListBox(string listType, object dataSource, Style style, HtmlTextWriter writer)
		{
			if (dataSource != null) {
				NameValueCollection list = GetList(listType, dataSource);
				if (list != null) {
					if (style != null) {
						style.AddAttributesToRender(writer);
					}
					writer.AddAttribute(HtmlTextWriterAttribute.Multiple, "multiple");
					writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID + "_" + listType);
					writer.RenderBeginTag(HtmlTextWriterTag.Select);
					for (int i = 0; i <= list.Count - 1; i++) {
						writer.AddAttribute(HtmlTextWriterAttribute.Value, list.Get(i));
						writer.RenderBeginTag(HtmlTextWriterTag.Option);
						writer.Write(list.GetKey(i));
						writer.RenderEndTag();
					}
					writer.RenderEndTag();
				}
			}
		}
		private void RenderHeader(HtmlTextWriter writer)
		{
			writer.RenderBeginTag(HtmlTextWriterTag.Tr);
			if (HeaderStyle != null) {
				HeaderStyle.AddAttributesToRender(writer);
			}
			writer.RenderBeginTag(HtmlTextWriterTag.Td);
			writer.Write(Localization.GetString(this.ID + "_Available", LocalResourceFile));
			writer.RenderEndTag();
			writer.RenderBeginTag(HtmlTextWriterTag.Td);
			writer.RenderEndTag();
			if (HeaderStyle != null) {
				HeaderStyle.AddAttributesToRender(writer);
			}
			writer.RenderBeginTag(HtmlTextWriterTag.Td);
			writer.Write(Localization.GetString(this.ID + "_Selected", LocalResourceFile));
			writer.RenderEndTag();
			writer.RenderEndTag();
		}
		private void RenderListBoxes(HtmlTextWriter writer)
		{
			writer.RenderBeginTag(HtmlTextWriterTag.Tr);
			writer.RenderBeginTag(HtmlTextWriterTag.Td);
			RenderListBox("Available", AvailableDataSource, AvailableListBoxStyle, writer);
			writer.RenderEndTag();
			writer.RenderBeginTag(HtmlTextWriterTag.Td);
			RenderButtons(writer);
			writer.RenderEndTag();
			writer.RenderBeginTag(HtmlTextWriterTag.Td);
			RenderListBox("Selected", SelectedDataSource, SelectedListBoxStyle, writer);
			writer.RenderEndTag();
			writer.RenderEndTag();
		}
		protected void OnAddButtonClick(DualListBoxEventArgs e)
		{
			if (AddButtonClick != null) {
				AddButtonClick(this, e);
			}
		}
		protected void OnAddAllButtonClick(EventArgs e)
		{
			if (AddAllButtonClick != null) {
				AddAllButtonClick(this, e);
			}
		}
		protected void OnRemoveButtonClick(DualListBoxEventArgs e)
		{
			if (RemoveButtonClick != null) {
				RemoveButtonClick(this, e);
			}
		}
		protected void OnRemoveAllButtonClick(EventArgs e)
		{
			if (RemoveAllButtonClick != null) {
				RemoveAllButtonClick(this, e);
			}
		}
		protected override void OnPreRender(System.EventArgs e)
		{
			base.OnPreRender(e);
			if (Page != null) {
				this.Page.RegisterRequiresPostBack(this);
			}
		}
		protected override void RenderContents(HtmlTextWriter writer)
		{
			if (ContainerStyle != null) {
				ContainerStyle.AddAttributesToRender(writer);
			}
			writer.RenderBeginTag(HtmlTextWriterTag.Table);
			RenderHeader(writer);
			RenderListBoxes(writer);
			writer.RenderEndTag();
		}
		public void RaisePostBackEvent(string eventArgument)
		{
			switch (eventArgument) {
				case "Add":
					OnAddButtonClick(new DualListBoxEventArgs(_AddValues));
					break;
				case "AddAll":
					OnAddAllButtonClick(new EventArgs());
					break;
				case "Remove":
					OnRemoveButtonClick(new DualListBoxEventArgs(_RemoveValues));
					break;
				case "RemoveAll":
					OnRemoveAllButtonClick(new EventArgs());
					break;
			}
		}
		public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
		{
		    bool retValue = Null.NullBoolean;
			string addItems = postCollection[postDataKey + "_Available"];
			if (!string.IsNullOrEmpty(addItems)) {
				_AddValues = new List<string>();
				foreach (string addItem in addItems.Split(',')) {
					_AddValues.Add(addItem);
				}
			    retValue = true;
			}
			string removeItems = postCollection[postDataKey + "_Selected"];
			if (!string.IsNullOrEmpty(removeItems)) {
				_RemoveValues = new List<string>();
				foreach (string removeItem in removeItems.Split(',')) {
					_RemoveValues.Add(removeItem);
				}
                retValue = true;
			}
            return retValue;
		}
		public void RaisePostDataChangedEvent()
		{
		}
	}
}
